 #if _MSC_VER
  #pragma once
 #endif

#ifndef __APPUTIL_TIMER_INCLUDED__
 #define __APPUTIL_TIMER_INCLUDED__
 #include "AppUtilTimerView.hxx"

HerzeleidTimingNamespaceBegin class Timer : public TimerView
{
private:

	typedef Void (Timer::*UpdateDelegate)();
	UpdateDelegate	m_UpdateCallback; 
	
	REIGN_FORCEINLINING Void UpdateNonfixedStepImpl()
	{
		auto const High = _To_single (m_CurrentTicks64 - m_LastTicks64);
		auto const Low = _To_single m_TicksPerSecond64;
		m_fDelta = (High / Low);
	}

	REIGN_FORCEINLINING Void UpdateFixedStepImpl()
	{
		m_fDelta = m_fFixedDelta;
	}

public:

	Void SetFixedTimeStep( Float32Const fStep );
	DeclGetPropOnly( TimerViewConstPtrConst, View ); // Gets timer view
	REIGN_FORCEINLINING DeclConstTypedGetterFor( TimerViewConstPtrConst, View ) { return this; } // Gets timer view

	Timer();
	Void Reset();

	REIGN_HINTINLINING Void Update()
	{
		m_LastTicks64 = m_CurrentTicks64;
		QueryPerformanceCounter( _Outptr_opt_ _To_large_int_ptr &m_CurrentTicks64 );
		(this->*m_UpdateCallback)();

		auto const High = _To_single (m_CurrentTicks64 - m_OneSecondTicks64);
		auto const Low = _To_single m_TicksPerSecond64;
		auto const Value = (High / Low);

		if ( Value < 1.0f ) m_iFrameCount++;
		else
		{
			m_OneSecondTicks64 = m_CurrentTicks64;
			m_iFramesPerSecond = m_iFrameCount;
			m_iFrameCount = 0;

			// Not useful for now
			// Uncomment to evaluate max fps
			//if ( m_iFramesPerSecond > m_iMaxFramesPerSecond )
				//m_iMaxFramesPerSecond = m_iFramesPerSecond;
		}
	}


} HerzeleidTimingNamespaceEnd; 

//#ifdef REIGN_DESKTOP
HerzeleidTimingNamespaceBegin
	TinyTypeDecl( Timer );
HerzeleidTimingNamespaceEnd
//#endif

#endif // !HERZELEID_TIMER_INCLUDED__